package com.easydev.mq.rabbit.listener;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.rabbitmq.client.Channel;

public abstract class RabbitAdvancedMessageListener extends RabbitMessageListener {
    private final static Logger LOGGER = LoggerFactory.getLogger(RabbitAdvancedMessageListener.class);

    // 是否自动创建QUEUE，如果true则queue为空时，自动创建一个非持久化、独立的、自动删除的队列，且名字是随机生成的
    private boolean autoCreateQueue = false;

    /**
     * @param queue 队列名 ，如果不填在autoCreateQueue为TRUE的情况下会自动创建QUEUE
     * @param exchange 转发器名称 如果不为空则绑定QUEUE与转发器
     * @param routings 路由规则，多个以","分隔 如果不为空则绑定规则
     * @param autoCreateQueue 是否自动创建QUEUE，如果true则queue为空时，自动创建一个非持久化、独立的、自动删除的队列，且名字是随机生成的
     * @throws Exception
     */
    public RabbitAdvancedMessageListener(String queue, String exchange, String routings, boolean autoCreateQueue)
            throws Exception {
        this.autoCreateQueue = autoCreateQueue;
        start(queue, exchange, routings, "");
    }

    /**
     * @param queue 队列名 ，如果不填在autoCreateQueue为TRUE的情况下会自动创建QUEUE
     * @param exchange 转发器名称 如果不为空则绑定QUEUE与转发器
     * @param routings 路由规则，多个以","分隔 如果不为空则绑定规则
     * @param autoCreateQueue 是否自动创建QUEUE，如果true则queue为空时，自动创建一个非持久化、独立的、自动删除的队列，且名字是随机生成的
     * @throws Exception
     */
    public RabbitAdvancedMessageListener(String queue, String exchange, String routings, boolean autoCreateQueue,
            String virtualHost) throws Exception {
        this.autoCreateQueue = autoCreateQueue;
        start(queue, exchange, routings, virtualHost);
    }

    /**
     * Description: 开启消息监听<br>
     * 
     * @author lx<br>
     * @param queue 队列名
     * @param exchange 转发器名称
     * @param routings 路由规则，多个以","分隔
     * @throws Exception <br>
     */
    private void start(String queue, String exchange, String routings, String virtualHost) throws Exception {
        Channel channel = channelPool.borrowObject(virtualHost);
        if (StringUtils.isBlank(queue) && autoCreateQueue) {
            // 创建一个非持久化、独立的、自动删除的队列，且名字是随机生成的
            queue = channel.queueDeclare().getQueue();
        }
        // 建立队列与转换器关系，并配置规则
        if (StringUtils.isNotBlank(queue) && StringUtils.isNotBlank(exchange)) {
            if (StringUtils.isNotBlank(routings)) {
                for (String routing : routings.split(",")) {
                    channel.queueBind(queue, exchange, routing);
                }
            } else {
                channel.queueBind(queue, exchange, routings);
            }
        }
        dealMessage(queue, channel);
    }

    @Override
    public abstract void handleMessage(String message) throws Exception;

    @Override
    public void handleFailedMessage(String message) {
        LOGGER.error("deal message failed,message is " + message);
    }

}
